#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * AbstractTestCase.java
 * Modification History
 * *************************************************************
 * Date				Author			Comment
 * Oct 17, 2012			Venkaiah Chowdary Koneru			Created
 * *************************************************************
 */
package ${package}.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.JDBCException;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;

/**
 * @author Venkaiah Chowdary Koneru
 * 
 */
public final class UtilTestCase
{
    /**
     * 
     * @param datasource
     * @throws IOException
     * @throws SQLException
     */
    public static void setupContext() throws SQLException, IOException
    {
        BasicDataSource localDataSource = getDataSourceFromSessionFactory(false);

        // START - dump test dummy data into HSQLDB
        Connection connection = null;
        Statement statement = null;
        long lineNo = 0L;
        BufferedReader reader = null;

        try
        {
            Resource re = new ClassPathResource("test-data.sql");
            connection = localDataSource.getConnection();
            statement = connection.createStatement();

            lineNo = 0L;
            reader = new BufferedReader(new InputStreamReader(
                    re.getInputStream()));

            for (String sql = reader.readLine(); sql != null; sql = reader
                    .readLine())
            {
                lineNo++;
                String trimmedSql = sql.trim();
                if (trimmedSql.length() == 0 || trimmedSql.startsWith("--")
                        || trimmedSql.startsWith("//")
                        || trimmedSql.startsWith("/*"))
                {
                    continue;
                }
                else
                {
                    statement.executeUpdate(trimmedSql);
                }
            }
        }
        catch (SQLException e)
        {
            throw new JDBCException("line no " + lineNo, e);
        }
        finally
        {
            if (statement != null)
            {
                statement.close();
            }
            if (connection != null)
            {
                connection.close();
            }
            if (reader != null)
            {
                reader.close();
            }
        }
        // FINISH - dump dummy test data
    }

    /**
     * 
     * @param datasource
     * @throws SQLException
     * @throws IOException
     */
    public static void afterTestMethod() throws SQLException, IOException
    {
        BasicDataSource localDataSource = getDataSourceFromSessionFactory(true);

        Connection connection = null;
        Statement statement = null;

        try
        {
            // Flush the HSQL DB
            connection = localDataSource.getConnection();
            statement = connection.createStatement();
            statement.execute("TRUNCATE SCHEMA public AND COMMIT");
        }
        catch (SQLException e)
        {
            throw new JDBCException("", e);
        }
        finally
        {
            if (statement != null)
            {
                statement.close();
            }
            if (connection != null)
            {
                connection.close();
            }
        }
    }

    /**
     * 
     * @param datasource
     * @return
     * @throws IOException
     * @throws SQLException
     */
    private static BasicDataSource getDataSourceFromSessionFactory(boolean drop)
            throws IOException, SQLException
    {
        LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
        lsfb.setConfigLocation(new ClassPathResource("hibernate-test.cfg.xml"));

        BasicDataSource localDataSource = new BasicDataSource();
        localDataSource.setDriverClassName("org.hsqldb.jdbcDriver");
        //TODO: update the database configs here once project is created.
        localDataSource.setPassword("");
        localDataSource.setUsername("${parentArtifactId}");
        localDataSource.setUrl("jdbc:hsqldb:mem:${parentArtifactId}");
        localDataSource.setMaxActive(20);
        localDataSource.setMaxWait(180000);
        localDataSource.setPoolPreparedStatements(true);

        lsfb.setDataSource(localDataSource);
        lsfb.afterPropertiesSet();

        SchemaExport schema = new SchemaExport(lsfb.getConfiguration());
        schema.setHaltOnError(true);
        schema.setFormat(false);
        schema.setDelimiter(";");

        if (!drop)
        {
            schema.execute(false, true, false, true);
        }
        else
        {
            schema.execute(false, true, true, false);
        }
        return localDataSource;
    }

    /**
     * private constructor for non-instatiability
     */
    private UtilTestCase()
    {
    }
}
